#ifndef _FS_H_
#define _FS_H_

#include <type.h>

#define SIZE_BLOCK	4096
#define SIZE_SECTOR	512
#define SEC_BLK		(SIZE_BLOCK / SIZE_SECTOR)
#define INODE_BLK	(SIZE_BLOCK / sizeof(struct inode))
#define ENTRY_BLK	(SIZE_BLOCK / sizeof(struct entry))

#define LEN_FILENAME	60
#define NUM_IZONE	9

#define P_INODE_DATA	(8 * INODE_BLK)

/* sizeof(struct entry) = 64 */
struct entry {
	char	name[LEN_FILENAME];
	u32_t	inode_nr;
};


/* File types. */
#define FT_FILE		1
#define FT_DIR		2

/* File mode. */
#define FM_READ		1
#define FM_WRITE	2
#define FM_EXEC		4

#define SEEK_SET	0
#define SEEK_CUR	1
#define SEEK_END	2

#define OF_READ		1
#define OF_WRITE	2


/* sizeof(struct inode) = 64 */
struct inode {
	u16_t	uid;
	u16_t	gid;
	u16_t	type;
	u16_t	mode;
	u32_t	c_time;
	u32_t	m_time;
	u32_t	a_time;
	u32_t	size;
	u32_t	nlinks;
	u32_t	i_zones[NUM_IZONE];
};
#define SIZE_INODE	sizeof(struct inode)

struct openfile {
	struct inode	*inode_pt;
	u32_t		inode_nr;
	u32_t		pos;
	u32_t		oflag;
};

struct super_block {
	struct inode	zero;		// root inode
	struct inode	root;		// root inode

	u32_t		size_block;	// size of block
	u32_t		blocks;		// number of blocks

	u32_t		imap_blks;	// number of inode-map blocks
	u32_t		dmap_blks;	// number of data-map blocks

	u32_t		d_blks;		// number of data blocks
	u32_t		i_blks;		// number of inode blocks
	u32_t		inodes;		// number of inodes

	u32_t		free_d_blks;	// number of free data blocks
	u32_t		free_inodes;	// number of free inodes

	u32_t		begin_iblk;	// first i_blk
	u32_t		begin_dblk;	// first d_blk
};

int lseek(int file, int offset, int flag);
int mkdir(const char *name);
int rmdir(const char *name);
int open(const char *fname, int flag);
int rm(const char *fname);
int read(int file, char *buf, int size);
int write(int file, const char *buf, int size);
int stat(int i, struct inode *stat);
int opendir(const char *dir);
int readdir(int, char *fname);
void close(int);

#endif /* _FS_H_*/
